package JavaSE.BLS.SystemShiftOperator;


/**
 *
 *
 * << ： 左位移运算符
 * >> ： 右位移运算符
 * >>> ： 无符号右位移
 *
 * 有符号左移N位，结果是 数字 乘以 2n次方
 * 有符号右移N位，结果是 数字 除以 2n次方
 *
 * 10 << 2 = 10 * 2的2次方 = 40
 * 10 >> 2 = 10 / 2的2次方 = 2
 *
 */
public class ShiftOperator
{
    
    public static void main(String[] args)
    {
        ShiftOperator sp = new ShiftOperator();
        sp.printPositiveNum(10);
        sp.printNegativeNum(-10);
        //可以输出 0 和 1 在计算机中的二进制表示：
        System.out.println(Integer.toBinaryString(0));
        System.out.println(Integer.toBinaryString(-1));
    }
    
    /**
     *
     * 正数的原码、反码、补码相同
     *
     * 10
     * 原码：0000 0000 0000 0000 0000 0000 0000 1010
     * 反码：0000 0000 0000 0000 0000 0000 0000 1010
     * 补码：0000 0000 0000 0000 0000 0000 0000 1010
     */
    public void printPositiveNum(int x){
        System.out.println(x >> 2);
        //原码/反码/补码：0000 0000 0000 0000 0000 0000 0000 1010
        //移位后原码/反码/补码：0000 0000 0000 0000 0000 0000 0000 0010 = 2
        System.out.println(x << 2);
        //原码/反码/补码：0000 0000 0000 0000 0000 0000 0000 1010
        //移位后原码/反码/补码：0000 0000 0000 0000 0000 0000 0010 1000 = 40
        System.out.println(x >>> 2);
        //原码/反码/补码：0000 0000 0000 0000 0000 0000 0000 1010
        //移位后原码/反码/补码：0000 0000 0000 0000 0000 0000 0000 0010 = 2
    }
    
    
    /**
     *
     * 负数
     * 反码 = 原码符号位不变，其他位取反
     * 补码 = 反码 + 1
     *
     * -10
     * 原码：1000 0000 0000 0000 0000 0000 0000 1010
     * 反码：1111 1111 1111 1111 1111 1111 1111 0101
     * 补码：1111 1111 1111 1111 1111 1111 1111 0110
     *
     */
    public void printNegativeNum(int x){
        System.out.println(x >> 2);
        //原码：1000 0000 0000 0000 0000 0000 0000 1010
        //反码：1111 1111 1111 1111 1111 1111 1111 0101
        //补码：1111 1111 1111 1111 1111 1111 1111 0110
        //移动后补码：1111 1111 1111 1111 1111 1111 1111 1101
        //转化为反码（补码-1）：1111 1111 1111 1111 1111 1111 1111 1100
        //转化为原码（反码取反）：1000 0000 0000 0000 0000 0000 0000 0011
        System.out.println(x << 2);
        //原码：1000 0000 0000 0000 0000 0000 0000 1010
        //反码：1111 1111 1111 1111 1111 1111 1111 0101
        //补码：1111 1111 1111 1111 1111 1111 1111 0110
        //移动后补码：11 1111 1111 1111 1111 1111 1101 1000
        //转化为反码（补码-1）：11 1111 1111 1111 1111 1111 1101 0111
        //转化为原码（反码取反）：10 0000 0000 0000 0000 0000 0010 1000
        System.out.println(x >>> 2);
        /**因为是无符号右移，所以负数变成正数，正数的补码就是原码，所以负数不用在将补码转化为原码*/
        //原码：1000 0000 0000 0000 0000 0000 0000 1010
        //反码：1111 1111 1111 1111 1111 1111 1111 0101
        //补码：1111 1111 1111 1111 1111 1111 1111 0110
        //移动后补码：0011 1111 1111 1111 1111 1111 1111 1101
    }


}
